package com.sfac.javaSpringCloudAccount.service.impl;

import com.github.pagehelper.PageHelper;
import com.github.pagehelper.PageInfo;
import com.sfac.entity.account.User;
import com.sfac.entity.account.UserRole;
import com.sfac.entity.common.Result;
import com.sfac.entity.common.SearchBean;
import com.sfac.entity.test.City;
import com.sfac.javaSpringCloudAccount.dao.UserDao;
import com.sfac.javaSpringCloudAccount.dao.UserRoleDao;
import com.sfac.javaSpringCloudAccount.entity.UserVo;
import com.sfac.javaSpringCloudAccount.service.UserService;
import com.sfac.javaSpringCloudAccount.util.MD5Util;
import org.springframework.beans.BeanUtils;
import org.springframework.beans.factory.annotation.Autowired;
import org.springframework.stereotype.Service;
import org.springframework.transaction.annotation.Transactional;
import org.springframework.web.client.RestTemplate;

import javax.security.auth.Subject;
import java.time.LocalDateTime;
import java.util.Collections;
import java.util.List;
import java.util.Optional;

/**
 * @Description: User Service Impl
 * @author: HymanHu
 * @date: 2021年2月21日
 */
@Service
public class UserServiceImpl implements UserService {
	
	@Autowired
	private UserDao userDao;
	@Autowired
	private UserRoleDao userRoleDao;
	@Autowired
	private RestTemplate restTemplate;

	@Override
	public User getUserByUserNameAndPassword(String userName, String password) {
		return userDao.getUserByUserNameAndPassword(userName, MD5Util.getMD5(password));
	}

	@Override
	public User getUserByUserName(String userName) {
		List<User> users = Optional
				.ofNullable(userDao.getUserByUserName(userName))
				.orElse(Collections.emptyList());
		return users.isEmpty() ? null : users.get(0);
	}

	@Override
	public Result<User> login(User user) {
		User userTemp = userDao.getUserByUserNameAndPassword(user.getUserName(), user.getPassword());
		if (userTemp==null){
			return new Result<>(Result.ResultCode.FAILED.code,"failed");

		}

		/*// 获得 subject
		Subject subject = SecurityUtils.getSubject();

		// 包装令牌
		UsernamePasswordToken token = new UsernamePasswordToken(
				user.getUserName(),
				MD5Util.getMD5(user.getPassword()));
		token.setRememberMe(user.getRememberMe());

		try {
			// 调用 subject login 方法，进行身份验证
			subject.login(token);
			// 调用 subjectcheck roles 方法，进行资源授权
			subject.checkRoles();
			// 处理 session
			subject.getSession().setAttribute("user", subject.getPrincipal());

		} catch (UnknownAccountException e) {
			return new Result<User>(Result.ResultCode.FAILED.code, e.getMessage());
		}*/
		// 返回 result
		return new Result<User>(Result.ResultCode.SUCCESS.code, "Success",userTemp);
	}

	@Override
	public void logout() {
		/*Subject subject = SecurityUtils.getSubject();
		subject.logout();*/
	}

	@Override
	@Transactional
	public Result<User> insertUser(User user) {
		List<User> users = Optional
				.ofNullable(userDao.getUserByUserNameOrEmail(user.getEmail(), user.getUserName()))
				.orElse(Collections.emptyList());
		if (users.size() > 0) {
			return new Result<User>(Result.ResultCode.FAILED.code, "User Name or email is repeat.");
		}

		user.setCreatDate(LocalDateTime.now());
//		user.setCreateDate(LocalDateTime.now());
		user.setPassword(MD5Util.getMD5(user.getPassword()));
		userDao.insertUser(user);
		if (user.getRoles() != null) {
			user.getRoles().stream()
				.forEach(item -> {userRoleDao.insertUserRole(new UserRole(user.getId(), item.getId()));});
		}
		return new Result<User>(Result.ResultCode.SUCCESS.code, "Insert success", user);
	}

	@Override
	@Transactional
	public Result<User> updateUser(User user) {
		List<User> users = Optional
				.ofNullable(userDao.getUserByUserNameOrEmail(user.getEmail(), user.getUserName()))
				.orElse(Collections.emptyList());
		if (users.stream().filter(item -> item.getId() != user.getId()).count() > 0) {
			return new Result<User>(Result.ResultCode.FAILED.code, "User Name or email is repeat.");
		}
		
		userDao.updateUser(user);
		if (user.getRoles() != null && !user.getRoles().isEmpty()) {
			userRoleDao.deleteUserRoleByUserId(user.getId());
			user.getRoles().stream()
				.forEach(item -> {userRoleDao.insertUserRole(new UserRole(user.getId(), item.getId()));});
		}
		
		return new Result<User>(Result.ResultCode.SUCCESS.code, "Update success", user);
	}

	@Override
	public User getUserById(int id) {
		return userDao.getUserById(id);
	}

	@Override
	@Transactional
	public Result<Object> deleteUserById(int id) {
		userDao.deleteUserById(id);
		userRoleDao.deleteUserRoleByUserId(id);
		return new Result<Object>(Result.ResultCode.SUCCESS.code, "Delete success");
	}

	@Override
	public PageInfo<User> getUsersBySearchBean(SearchBean searchBean) {
		searchBean.initSearchBean();
		PageHelper.startPage(searchBean.getCurrentPage(), searchBean.getPageSize());
		return new PageInfo<User>(Optional
				.ofNullable(userDao.getUsersBySearchVo(searchBean))
				.orElse(Collections.emptyList()));
	}

	@Override
	public List<User> getUsersByKeyWord(String keyWord) {
		SearchBean searchBean = new SearchBean();
		searchBean.setKeyword(keyWord);
		searchBean.initSearchBean();
		return Optional.ofNullable(userDao.getUsersBySearchVo(searchBean)).orElse(Collections.emptyList());
	}

	@Override
	public UserVo getUserVoById(int id) {
		UserVo userVo = new UserVo();
		User user = userDao.getUserById(id);
		BeanUtils.copyProperties(user,userVo);
		//TODO
//		restTemplate.getForEntity();
		City city = restTemplate.getForObject("http://client-test/api/test/city/{cityId}", City.class, 1890);
		userVo.setCity(city);
		return userVo;
	}
}
